package cn.itbeien.core.util;

import org.apache.commons.codec.digest.DigestUtils;

import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @author beien
 * @date 2024-03-11 16:34
 * Copyright© 2024 beien
 */
public class WexinJSSign {
    /**
     *
     * 微信支付签名相关工具
     * 签名字符串
     *
     * @param text 待加密的文本数据
     * @param key 密钥
     * @param input_charset 字符集  UTF-8
     * @return 签名结果
     */
    public static String sign(String text, String key, String input_charset) {
        text = text + "&key=" + key;
        return DigestUtils.md5Hex(getContentBytes(text, input_charset));
    }


    /**
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);//安装字典序进行排序
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        //appid='123456'&timestamp=111111&
        return prestr;
    }

    public static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }

    public static void main(String[] args) {
        //组装参数，生成下单所需要的参数map进行第一次签名
        Map<String, String> packageParams = new HashMap<>();
        packageParams.put("appid", "wx2421b1c4370ec43b");//预支付返回的appid
        packageParams.put("timeStamp", "1710126482");//自己生成unix时间戳
        packageParams.put("nonce_str", "269d5b6c3b5948d2b7ddc8d3d523d639");//自己生成的随机字符串
        packageParams.put("package","prepay_id=123456789");//预支付订单返回的预支付订单id

        //所有元素排序(字典序-ascii)，并按照“参数=参数值”的模式用
        // “&”字符拼接成字符串,用来签名
        String preStr = createLinkString(packageParams);
        //md5签名  返回的签名数据转为大写
        String sign = sign(preStr, "key", "utf-8").toUpperCase();
    }
}
